package cn.caplike.demo.apache.thrift;

import org.apache.thrift.TProcessorFactory;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.server.THsHaServer;
import org.apache.thrift.server.TServer;
import org.apache.thrift.transport.TNonblockingServerSocket;
import org.apache.thrift.transport.TTransportException;
import org.apache.thrift.transport.layered.TFramedTransport;
import thrift.generated.PersonService;

/**
 * Description: Thrift network stack.
 * <pre>
 * +-------------------------------------------+
 * | Server                                    |
 * | (single-threaded, event-driven etc)       |
 * +-------------------------------------------+
 * | Processor                                 |
 * | (compiler generated)                      |
 * +-------------------------------------------+
 * | Protocol                                  |
 * | (JSON, compact etc)                       |
 * +-------------------------------------------+
 * | Transport                                 |
 * | (raw TCP, HTTP etc)                       |
 * +-------------------------------------------+
 * </pre>
 * <hr>
 * <br>Thrift 传输格式:
 * <ul>
 *     <li>TBinaryProtocol: 二进制格式</li>
 *     <li>{@link TCompactProtocol}: 压缩格式 (效率比 Binary 更高)</li>
 *     <li>TJSONProtocol: JSON 格式</li>
 *     <li>TSimpleJSONProtocol: 提供 JSON 只写协议 (缺少 Metadata), 生成的文件很容易通过脚本语言解析</li>
 *     <li>TDebugProtocol: 易懂的可读的文本格式, 便于调试</li>
 * </ul>
 * <br>Thrift 数据传输方式:
 * <ul>
 *     <li>TSocket: 阻塞式 socket</li>
 *     <li>{@link TFramedTransport}: 以 frame 为单位进行传输, 非阻塞式服务中使用</li>
 *     <li>TFileTransport: 以文件形式传输</li>
 *     <li>TMemoryTransport: 将内存用于 I/O, Java 实现时内部实际使用了简单的 ByteArrayOutputStream</li>
 *     <li>: 使用 zlib 进行压缩, 与其他传输方式联合使用. 当前无 Java 实现</li>
 * </ul>
 * <br>Thrift 支持的服务模型:
 * <ul>
 *     <li>TSimpleServer: 简单的单线程服务模型, 常用于测试</li>
 *     <li>TThreadPoolServer: 多线程服务模型, 使用标准的阻塞式 IO</li>
 *     <li>TNonBlockingServer: 多线程服务模型, 使用非阻塞式 IO (需使用 TFramesTransport 数据传输方式)</li>
 *     <li>{@link THsHaServer}: THsHa 引入了线程池去处理, 其模型把读写任务放到线程池去处理; Half-sync/Half-async 的处理模式, Half-async 是在处理 IO 事件上 (accept/read/write io), Half-sync 用于 Handler 对 rpc 的同步处理 (需使用 TFramesTransport 数据传输方式)</li>
 * </ul>
 *
 * @author LiKe
 * @version 1.0.0
 * @date 2021-12-06 13:18
 */
public class ThriftServer {

    public static void main(String[] args) throws TTransportException {
        TNonblockingServerSocket socket = new TNonblockingServerSocket(8899);
        THsHaServer.Args arg = new THsHaServer.Args(socket).minWorkerThreads(2).maxWorkerThreads(4);

        PersonService.Processor<PersonServiceImpl> processor = new PersonService.Processor<>(new PersonServiceImpl());

        arg.protocolFactory(new TCompactProtocol.Factory());   // 协议层 (上层) 传输格式 1
        arg.transportFactory(new TFramedTransport.Factory());  // 传输层 (底层) 传输方式 2
        arg.processorFactory(new TProcessorFactory(processor));

        TServer server = new THsHaServer(arg); // Half sync, Half async 服务模型 3
        System.out.println("ThriftServer Started");
        server.serve();
    }
}
